package msu.ml.data;

import msu.ml.core.*;
import msu.ml.util.*;
import java.util.*;

public class DatabaseCache
{
    private DatabaseDataLoader dbLoader;
    private CacheDataLoader cacheLoader;

    public DatabaseCache(String url, String user, String pass)
    {
        dbLoader = new DatabaseDataLoader(url, user, pass);
        cacheLoader = new CacheDataLoader();
    }

    public void clear()
    {
        cacheLoader.clear();
    }

    public NxInstances retrieve(String sig)
    {
        return cacheLoader.load(createKey(sig));
    }

    public NxInstances retrieveByKey(String key)
    {
        return cacheLoader.load(key);
    }

    public NxInstances retrieve(String name, 
        ArrayList<IDataPreProcessor> filters)
    {
        String sig = createSignature(name, filters);
        String key = createKey(sig);

        if(cacheLoader.isSupportedData(key))
        {
            return cacheLoader.load(key);
        }
        else if(dbLoader.isSupportedData(name))
        {
            NxInstances data = dbLoader.load(name, filters);
            for(IDataPreProcessor filter : filters)
                data = filter.process(data);
            cacheLoader.store(data, key);
            cacheLoader.synch();
            return data;
        }
    
        return null;
    }

    public void setRawDataDirectory(String path)
    {
        this.dbLoader.setLocalDataDirectory(path);
    }

    public String store(NxInstances data, String sig)
    {
        String key = createKey(sig);
        cacheLoader.store(data, key);
        return key;
    }

    public static String createSignature(String name,
        ArrayList<IDataPreProcessor> filters)
    {
        String result = 
        "<?xml version=\"1.0\"?>" +
            "<cache_signature>" +
                "<target>" + name + "</target>";

        String [] filterStrings = new String[filters.size()];
        for(int i = 0; i < filters.size(); i++)
            filterStrings[i] = filters.get(i).toString();
        Arrays.sort(filterStrings);
        result += "<filters>"; 
        for(int i = 0; i < filterStrings.length; i++)
            result += filterStrings[i];
        result += "</filters></cache_signature>";

        return result;
    }

    public static String createKey(String sig)
    {
        return StringUtility.getMD5(sig);
    }
}
